---
title: "Example: Control Flow | Workflows | Kastrax Docs"
description: Example of using Kastrax to create workflows with loops based on provided conditions.
---

import { GithubLink } from "@/components/github-link";

# Looping step execution ✅
This example demonstrates how to create a workflow that executes one or more of it's steps in a loop until a condition is met


## Define Looping workflow ✅
Defines a workflow which calls the executes a nested workflow until the provided condition is met.

```ts showLineNumbers copy filename="looping-workflow.ts"
import { createWorkflow, createStep } from '@kastrax/core/workflows/vNext'
import { z } from 'zod'

const incrementStep = createStep({
  id: 'increment',
  inputSchema: z.object({
    value: z.number(),
  }),
  outputSchema: z.object({
    value: z.number(),
  }),
  execute: async ({ inputData }) => {
    return { value: inputData.value + 1 }
  },
})

const sideEffectStep = createStep({
  id: 'side-effect',
  inputSchema: z.object({
    value: z.number(),
  }),
  outputSchema: z.object({
    value: z.number(),
  }),
  execute: async ({ inputData }) => {
    console.log('log', inputData.value)
    return { value: inputData.value }
  },
})

const finalStep = createStep({
  id: 'final',
  inputSchema: z.object({
    value: z.number(),
  }),
  outputSchema: z.object({
    value: z.number(),
  }),
  execute: async ({ inputData }) => {
    return { value: inputData.value }
  },
})

const workflow = createWorkflow({
  id: 'increment-workflow',
  inputSchema: z.object({
    value: z.number(),
  }),
  outputSchema: z.object({
    value: z.number(),
  }),
})
  .dountil(
    createWorkflow({
      id: 'increment-workflow',
      inputSchema: z.object({
        value: z.number(),
      }),
      outputSchema: z.object({
        value: z.number(),
      }),
      steps: [incrementStep, sideEffectStep],
    })
      .then(incrementStep)
      .then(sideEffectStep)
      .commit(),
    async ({ inputData }) => inputData.value >= 10
  )
  .then(finalStep)

workflow.commit()

export { workflow as incrementWorkflow }
```


## Register Workflow instance with Kastrax class ✅
Register the workflow with the kastrax instance.

```ts showLineNumbers copy filename="index.ts"
import { Kastrax } from '@kastrax/core/kastrax'
import { createLogger } from '@kastrax/core/logger'
import { incrementWorkflow } from './workflows'

const kastrax = new Kastrax({
  vnext_workflows: {
    incrementWorkflow,
  },
  logger: createLogger({
    name: 'Kastrax',
    level: 'info',
  }),
})

export { kastrax }
```


## Execute the workflow ✅
Here, we'll get the increment workflow from the kastrax instance, then create a run and execute the created run with the required inputData.

```ts showLineNumbers copy filename="exec.ts"
import { kastrax } from "./"

const workflow = kastrax.vnext_getWorkflow('incrementWorkflow')
const run = workflow.createRun()

const result = await run.start({ inputData: { value: 0 } })
console.dir(result, { depth: null })
```


<br />
<br />
<hr className="dark:border-[#404040] border-gray-300" />
<br />
<br />
<GithubLink
  link={
    "https://github.com/kastrax-ai/kastrax/blob/main/examples/basics/workflows/control-flow"
  }
/>

